package com.mtiiot.fstcpserver.fastdfs.core;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;

public class TrackerGroup {
	protected Integer lock;
	public int tracker_server_index;
	public InetSocketAddress[] tracker_servers;

	public TrackerGroup(InetSocketAddress[] tracker_servers) {
		this.tracker_servers = tracker_servers;
		this.lock = new Integer(0);
		this.tracker_server_index = 0;
	}

	public TrackerServer getConnection(int serverIndex) throws IOException {
		Socket sock = new Socket();
		sock.setReuseAddress(true);
		sock.setSoTimeout(ClientGlobal.g_network_timeout);
		sock.connect(this.tracker_servers[serverIndex],
				ClientGlobal.g_connect_timeout);
		return new TrackerServer(sock, this.tracker_servers[serverIndex]);
	}

	public TrackerServer getConnection() throws IOException {
		int current_index;
		synchronized (this.lock) {
			this.tracker_server_index += 1;
			if (this.tracker_server_index >= this.tracker_servers.length) {
				this.tracker_server_index = 0;
			}

			current_index = this.tracker_server_index;
		}

		try {
			return getConnection(current_index);
		} catch (IOException ex) {
			System.err.println("connect to server "
					+ this.tracker_servers[current_index].getAddress()
							.getHostAddress() + ":"
					+ this.tracker_servers[current_index].getPort() + " fail");
			ex.printStackTrace(System.err);

			for (int i = 0; i < this.tracker_servers.length; i++) {
				if (i != current_index) {
					try {
						TrackerServer trackerServer = getConnection(i);

						synchronized (this.lock) {
							if (this.tracker_server_index == current_index) {
								this.tracker_server_index = i;
							}
						}

						return trackerServer;
					} catch (IOException e) {
						System.err.println("connect to server "
								+ this.tracker_servers[i].getAddress()
										.getHostAddress() + ":"
								+ this.tracker_servers[i].getPort() + " fail");
						e.printStackTrace(System.err);
					}
				}
			}
		}
		return null;
	}

	public Object clone() {
		InetSocketAddress[] trackerServers = new InetSocketAddress[this.tracker_servers.length];
		for (int i = 0; i < trackerServers.length; i++) {
			trackerServers[i] = new InetSocketAddress(this.tracker_servers[i]
					.getAddress().getHostAddress(),
					this.tracker_servers[i].getPort());
		}

		return new TrackerGroup(trackerServers);
	}
}